package com.lmy.springboot_rabbitmq.service;

import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.UUID;

/**
 * 订单服务，生产者生产订单信息
 */
@Service
public class OrderProducerService {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 模拟用户下单 使用fanout发布订阅模式全发送
     * @param userId 用户id
     * @param productId 商品id
     * @param num 购买数量
     */
    public void makeOrder(String userId, String productId, int num) {

        //1.根据商品id，查询库存是否充足
        //2.保存订单
        String orderId = UUID.randomUUID().toString();
        System.out.println("订单生成成功:" + orderId);
        //3.通过消息队列来完成消息的分发，实现异步传输。这里使用fanout模式分发消息
        /*
            convertAndSend()有方法重载，各参数如下：
            1.交换机
            2.路由key，若为工作模式或简单模式，则为队列名称
            3.消息内容
         */
        String exchangeName = "fanout_order_exchange";
        String routingKey = "";
        rabbitTemplate.convertAndSend(exchangeName, routingKey, orderId);
    }

    /**
     * 模拟用户下单 使用direct 路由模式
     * @param userId 用户id
     * @param productId 商品id
     * @param num 购买数量
     */
    public void makeOrderDirect(String userId, String productId, int num) {

        //1.根据商品id，查询库存是否充足
        //2.保存订单
        String orderId = UUID.randomUUID().toString();
        System.out.println("订单生成成功:" + orderId);
        //3.通过消息队列来完成消息的分发，实现异步传输。这里使用direct模式分发消息
        /*
            convertAndSend()有方法重载，各参数如下：
            1.交换机
            2.路由key;若为工作模式或简单模式，则为队列名称
            3.消息内容
         */
        String exchangeName = "direct_order_exchange";
        //这里给短信和邮件发送消息
        String routingKey = "message";
        String routingKey2 = "email";
        rabbitTemplate.convertAndSend(exchangeName, routingKey, orderId);
        rabbitTemplate.convertAndSend(exchangeName, routingKey2, orderId);
    }

    /**
     * 模拟用户下单 使用direct 主题模式
     * @param userId 用户id
     * @param productId 商品id
     * @param num 购买数量
     */
    public void makeOrderTopic(String userId, String productId, int num) {

        //1.根据商品id，查询库存是否充足
        //2.保存订单
        String orderId = UUID.randomUUID().toString();
        System.out.println("订单生成成功:" + orderId);
        //3.通过消息队列来完成消息的分发，实现异步传输。这里使用topic模式分发消息
        /*
            convertAndSend()有方法重载，各参数如下：
            1.交换机
            2.路由key;若为工作模式或简单模式，则为队列名称
            3.消息内容
         */
        String exchangeName = "topic_order_exchange";
        //这里模拟向email sms message队列发送消息
        // #.sms.#
        // #.email.#
        // #.message.#
        String routingKey = "com.sms.email.message";
        rabbitTemplate.convertAndSend(exchangeName, routingKey, orderId);
    }

    /**
     * 模拟用户下单 测试队列的ttl过期时间
     * @param userId 用户id
     * @param productId 商品id
     * @param num 购买数量
     */
    public void makeOrderTtl(String userId, String productId, int num) {

        //1.根据商品id，查询库存是否充足
        //2.保存订单
        String orderId = UUID.randomUUID().toString();
        System.out.println("订单生成成功:" + orderId);
        //3.通过消息队列来完成消息的分发，实现异步传输。这里使用direct模式分发消息
        /*
            convertAndSend()有方法重载，各参数如下：
            1.交换机
            2.路由key;若为工作模式或简单模式，则为队列名称
            3.消息内容
         */
        String exchangeName = "ttl_direct_order_exchange";
        String routingKey = "ttl";
        rabbitTemplate.convertAndSend(exchangeName, routingKey, orderId);
    }

    /**
     * 模拟用户下单 测试消息的ttl过期时间
     * @param userId 用户id
     * @param productId 商品id
     * @param num 购买数量
     */
    public void makeOrderTtlMessage(String userId, String productId, int num) {

        //1.根据商品id，查询库存是否充足
        //2.保存订单
        String orderId = UUID.randomUUID().toString();
        System.out.println("订单生成成功:" + orderId);
        //3.通过消息队列来完成消息的分发，实现异步传输。这里使用direct模式分发消息
        /*
            convertAndSend()有方法重载，各参数如下：
            1.交换机
            2.路由key;若为工作模式或简单模式，则为队列名称
            3.消息内容
         */
        String exchangeName = "ttl_direct_order_exchange";
        String routingKey = "ttl_message";
        //给消息设置过期时间
        MessagePostProcessor messagePostProcessor = new MessagePostProcessor() {

            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                //给消息设置过期时间，单位ms
                message.getMessageProperties().setExpiration("5000");
                //给消息设置编码格式
                message.getMessageProperties().setContentEncoding("UTF-8");
                return message;
            }
        };
        rabbitTemplate.convertAndSend(exchangeName, routingKey, orderId, messagePostProcessor);
    }
}
